package com.boboPlanet.user.service.impl;

import com.boboPlanet.comm.context.BusinessStartTimeContext;
import com.boboPlanet.comm.context.LoginUserContext;
import com.boboPlanet.comm.entity.po.LoginUserInfoPO;
import com.boboPlanet.comm.rabbitmq.PlanetMqProducer;
import com.boboPlanet.comm.rabbitmq.producer.PlanetMqTopic;
import com.boboPlanet.comm.utils.AutoGenerateIds;
import com.boboPlanet.comm.utils.AvatarRandom;
import com.boboPlanet.user.async.AsyncTask;
import com.boboPlanet.user.entity.dto.ArticleDTO;
import com.boboPlanet.user.entity.dto.ArticleMainDTO;
import com.boboPlanet.user.entity.dto.ArticleMainInfoDTO;
import com.boboPlanet.user.entity.dto.SysLogDTO;
import com.boboPlanet.user.entity.po.ArtCollectPO;
import com.boboPlanet.user.entity.po.ArticleDetailPO;
import com.boboPlanet.user.entity.po.ArticleMainInfoPO;
import com.boboPlanet.user.entity.po.CommentInfoPO;
import com.boboPlanet.user.entity.vo.ArticleMainVO;
import com.boboPlanet.user.mq.PlanetMiddleMqEnum;
import com.boboPlanet.user.enums.SysOperatorEnum;
import com.boboPlanet.user.lock.DistributedLockFactory;
import com.boboPlanet.user.lock.impl.DistributedRedisLock;
import com.boboPlanet.user.mapper.ArticleDetailMapper;
import com.boboPlanet.user.mapper.ArticleMapper;
import com.boboPlanet.user.mapper.ArticleTypeMapper;
import com.boboPlanet.user.mapper.UserInfoConvert;
import com.boboPlanet.user.service.ArticleService;
import com.boboPlanet.user.single.SingleFactory;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @Description: TODO
 * @Author: mis_wu
 * @Date: 2023/2/22
 **/
@Service
@Slf4j
public class ArticleServiceImpl implements ArticleService {

    @Resource
    private ArticleMapper articleMapper;

    @Resource
    private ArticleDetailMapper articleDetailMapper;

    @Resource
    private ArticleTypeMapper articleTypeMapper;

    @Resource
    private DistributedLockFactory distributedLockFactory;

    @Resource
    private AsyncTask asyncTask;

    @Resource
    private PlanetMqTopic planetMqTopic;

    @Resource
    private PlanetMqProducer planetMqProducer;

    @Override
    public List<ArticleMainVO> getLogoutArticleMainInfo(ArticleMainDTO dto,boolean flag) {
        //todo: 读取是否分页配置,待定

        List<ArticleMainInfoDTO> mainPo = articleMapper.getLogoutArticleMainInfo(dto,flag);
        if (mainPo.isEmpty()){
            return Collections.emptyList();
        }
        List<ArticleMainVO> vos = UserInfoConvert.INSTANCE.artdtos2Vos(mainPo);
        vos.forEach(item -> {
            String[] types = item.getArticleTypeName().split(",");
            List<String> typeList = Arrays.asList(types);
            item.setArticleTypeNames(typeList);
        });
        return vos;
    }


    /**
     * todo：对文章内容智能审核
     * @param dto ArticleDTO
     * @return Boolean
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertArticleInfo(ArticleDTO dto) {
        if (dto == null){
            return false;
        }
        if (dto.getArticleTypeIds().isEmpty()){
            return false;
        }
        if (StringUtils.isBlank(dto.getArticleTitle())){
            return false;
        }
        if (StringUtils.isBlank(dto.getArticleContent())){
            return false;
        }
        //加锁
        DistributedRedisLock redisLock = distributedLockFactory.getRedisLock(dto.getArticleTitle()+Thread.currentThread().getId());
        try {
            //if (redisLock.tryLock(10, TimeUnit.SECONDS)){
                LoginUserInfoPO userInfo = LoginUserContext.getLoginUserInfoPO();
                ArticleMainInfoPO mainPo = new ArticleMainInfoPO();
                mainPo.setArticleId(AutoGenerateIds.getGenerateId());
                mainPo.setUserId(userInfo.getUserId());
                if (dto.getIsAnonymous() == 0){
                    mainPo.setArticleUser(userInfo.getUserName());
                    //todo:查询头像地址
                }else {
                    mainPo.setArticleUser("匿名用户"+System.currentTimeMillis());
                    dto.setUserAvatar(AvatarRandom.getAvatarPath());
                }
                mainPo.setAccountId(userInfo.getAccountId());

                StringBuilder types = new StringBuilder();
                for (Long typeId : dto.getArticleTypeIds()) {
                    types.append(typeId).append(",");
                }
                if (types.length() > 0){
                    types = new StringBuilder(types.substring(0, types.length() - 1));
                }
                mainPo.setArticleTypeId(types.toString());
                List<String> typeNames = articleTypeMapper.selectTypeNameByIds(dto.getArticleTypeIds());
                StringBuilder typeName = new StringBuilder();
                for (String name : typeNames) {
                    typeName.append(name).append(",");
                }
                if (typeName.length() > 0){
                    typeName = new StringBuilder(typeName.substring(0, typeName.length() - 1));
                }
                mainPo.setArticleTypeName(String.valueOf(typeName));
                mainPo.setArticleTitle(dto.getArticleTitle());
                mainPo.setIsAnonymous(dto.getIsAnonymous());
                mainPo.setPlanetUpdateTime(BusinessStartTimeContext.getTime());
                mainPo.setPlanetUpdateUser(userInfo.getUserName());
                mainPo.setArticleState(0);
                mainPo.setVersion(0);

                ArticleDetailPO detail = new ArticleDetailPO();
                detail.setArticleDetailId(AutoGenerateIds.getGenerateId());
                detail.setArticleId(mainPo.getArticleId());
                detail.setArticleContent(dto.getArticleContent());
                detail.setPlanetUpdateTime(BusinessStartTimeContext.getTime());
                detail.setPlanetUpdateUser(userInfo.getUserName());
                detail.setVersion(0);

                articleMapper.insert(mainPo);
                articleDetailMapper.insert(detail);

                //Es同步操作
                //planetMqTopic.build(PlanetMiddleMqEnum.ES_INSERT_ARTICLE).sendMsg(mainPo.getArticleId());
                //planetMqTopic.sendMsg(PlanetMiddleMqEnum.ES_INSERT_ARTICLE,mainPo.getArticleId());
                planetMqProducer.sendMsg(PlanetMiddleMqEnum.ES_INSERT_ARTICLE,mainPo.getArticleId());

                SysLogDTO logDto = SingleFactory.getLogDto(SysOperatorEnum.INSERT_ART.getDesc());
                asyncTask.tranceLog(logDto);

                return true;
            //}
        }catch (Exception e){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            log.error("add article fail, error reason is redis lock fail,detail is: {}",e.getMessage());
        }finally {
            //redisLock.unlock();
        }
        return false;
    }

    @Override
    public ArticleDetailPO getArtDetailById(Long artId) {

        return articleDetailMapper.queryDetailById(artId);

    }

    @Override
    public Boolean publishComment(Long artId,String content) {
        LoginUserInfoPO userInfo = LoginUserContext.getLoginUserInfoPO();
        CommentInfoPO po = new CommentInfoPO();
        po.setCommentId(AutoGenerateIds.getGenerateId());
        po.setArticleId(artId);
        po.setAccountId(userInfo.getAccountId());
        po.setUserId(userInfo.getUserId());
        po.setContent(content);
        po.setPlanetUpdateTime(BusinessStartTimeContext.getTime());
        po.setPlanetUpdateUser(userInfo.getUserName());

        SysLogDTO logDto = SingleFactory.getLogDto(SysOperatorEnum.PUBLISH_COMMENT.getDesc()+",artId:"+artId);
        asyncTask.tranceLog(logDto);

        return articleMapper.publishComment(po);
    }

    @Override
    public List<CommentInfoPO> getCommentList(Long artId) {
        return articleMapper.getCommentList(artId);
    }

    @Transactional(rollbackFor = Exception.class)
    public Boolean collectArt(Long artId){
        if (artId == null || artId < 0){
            return false;
        }
        LoginUserInfoPO userInfo = LoginUserContext.getLoginUserInfoPO();
        ArtCollectPO po = new ArtCollectPO();
        po.setCollectId(AutoGenerateIds.getGenerateId());
        po.setArtId(artId);
        po.setUserId(userInfo.getUserId());
        po.setCollectTime(BusinessStartTimeContext.getTime());
        po.setCollectUser(userInfo.getUserName());
        po.setPlanetUpdateTime(BusinessStartTimeContext.getTime());
        po.setPlanetUpdateUser(userInfo.getUserName());

        asyncTask.tranceLog(SingleFactory.getLogDto(SysOperatorEnum.COLLECT_ART.getDesc()));

        return articleMapper.collectArt(po);
    }

    /**
     * 同一个用户对一个文章只能收藏一次
     * @param artId Long
     * @return Boolean
     */
    @Override
    public Boolean cancelCollectArt(Long artId) {
        if (artId == null || artId < 0){
            return false;
        }
        LoginUserInfoPO userInfo = LoginUserContext.getLoginUserInfoPO();
        asyncTask.tranceLog(SingleFactory.getLogDto(SysOperatorEnum.CANCEL_COLLECT_ART.getDesc()));
        return articleMapper.cancelCollectArt(userInfo.getUserId(),artId);
    }

    @Override
    public Boolean judgeCurrentArtIsCollect(Long artId) {
        if (artId == null || artId <= 0){
            return false;
        }
        LoginUserInfoPO user = LoginUserContext.getLoginUserInfoPO();
        return articleMapper.judgeCurrentArtIsCollect(artId,user.getUserId()) > 0;
    }
}
